<?php


namespace app\common\model;


use app\common\service\redis\PoolRedis;
use app\model\AdminAttendanceRecord;
use app\model\AdminAttendanceSys;
use app\model\AdminClassroom;
use app\model\AdminStaff;
use app\util\ReturnCode;
use think\facade\Log;

class AttendanceVerityModel extends AdminAttendanceSys
{
    /**
     * @notes: 考勤规则检验
     * @param $staff AdminStaff
     * @param $deviceId 设备ID
     * @param $ruleId 规则ID
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function verity($staff, $deviceId, $ruleId)
    {
        // 判断是否已打卡
        $cacheKey = AdminAttendanceRecord::ATTENDANCE_COUNT_CACHE_KEY."{$ruleId}:".date('Y-m-d');
        $redis = PoolRedis::instance();
        $count = $redis->sismember($cacheKey, $staff['id']);
        if ($count == 1) {
            throw new \Exception('今日已打卡成功，无需重复打卡');
        }

        // 获取考勤规则
        $rule = self::getRulesByRuleId($staff->school_id, $ruleId);
        if (!$rule) {
            throw new \Exception('当前考勤规则不存在');
        }

        // 考勤日期判断
        if (strtotime($rule['start']) > time() || strtotime($rule['end']) < time()) {
            throw new \Exception('未在考勤时间，无需打卡');
        }

        // 考勤星期判断
        $week = date('w');
        if (!in_array($week, $rule['weeks'])) {
            throw new \Exception('未到考勤日期，无需打卡');
        }

        $STATUS = AdminAttendanceRecord::SUCCESS;
        $day = date('Y-m-d ');
        $now = time();
        $data = [];

        // 202300517 * 不区分教室宿舍
        // 当前时间 < 起始时间
        // 当前时间 > 结束时间
        if ($now < strtotime($day.$rule['start_hours'])
            || $now > strtotime($day.$rule['end_hours'])) {
            throw new \Exception('未在考勤时间，无需打卡');
        }
        $data['clock_no'] = 1;

        $data['attendance_id'] = $rule['id'];
        $data['hour'] = $rule['start_hours'].'~'.$rule['end_hours'];
        $data['scope'] = $rule['scope'];
        $data['classroom'] = $rule['classroom'];
        $data['status'] = $STATUS;

        // 判断打卡范围  优化速度-暂时取消
        if (!$data || false === self::resetRuleByScope($data, $staff, [$deviceId])) {
            throw new \Exception('不在考勤范围，无法打卡');
        }
        return $data;
    }

    /**
     * @notes: 返回符合规则的考勤，在指定的教室或宿舍范围内
     * @param $rule
     * @param $staff AdminStaff
     * @param $uuids 设备ID集合
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function resetRuleByScope(&$rule, $staff, $uuids)
    {
        $rule['dormitory_list'] = [];
        $rule['classroom_list'] = [];
        // 考勤宿舍范围
        if ($rule['scope'] == AdminAttendanceSys::SCOPE_DORMITORY) {
            $stu_dor_list = StudentModel::dormitoryBelongStudent($staff->id);
            foreach ($stu_dor_list as $item) {
                if (in_array($item['uuid'], $uuids)) {
                    $rule['dormitory_list'][] = $item;
                }
            }
        }
        // 考勤教室范围
        if ($rule['scope'] == AdminAttendanceSys::SCOPE_CLASSROOM) {
            $rule['classroom_list'] = AdminClassroom::where('school_id', $staff->school_id)
                ->where('is_delete', 0)
                ->where('id', 'in', $rule['classroom'])
                ->field('id,bluetooth_mac uuid,name')
                ->select()->toArray();
        }
        return sizeof($rule['dormitory_list']) > 0 || sizeof($rule['classroom_list']) > 0;
    }

    // 获取规则列表
    public static function getRules($staff)
    {
        $grade = $staff->grade;
        if (!$grade) {
            return [];
        }
        $key = AdminAttendanceSys::ATTENDANCE_CACHE_KEY.$staff->school_id;
        $redis = PoolRedis::instance();
        $res = $redis->get($key);
        if ($res) {
            return $res;
        }

        $query = AdminAttendanceSys::where([
            'school_id' => $staff->school_id,
            'is_delete' => 0,
            'status' => AdminAttendanceSys::ENABLE
        ]);
        $list = $query->field('id,title,start,end,weeks,start_hours,end_hours,scope,grade,classroom,update_time')
            ->order('update_time', 'desc')
            ->select()->toArray();
        if ($list) {
            $redis->set($key, $list);
        }
        return $list;
    }

    // 获取单个考勤规则
    public static function getRulesByRuleId($school_id, $ruleId)
    {
        $key = AdminAttendanceSys::ATTENDANCE_CACHE_KEY.$school_id;
        $redis = PoolRedis::instance();
        $res = $redis->get($key);
        if ($res) {
            foreach ($res as $item) {
                if ($item['id'] == $ruleId) {
                    return $item;
                }
            }
        }
        return null;
    }
}